package com.grao.waterschool.human.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.HttpMessageConverterExtractor;
import org.springframework.web.client.ResponseExtractor;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

public class NoExceptionRestTemplateResponseEntityExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {

    private static final Logger log = LoggerFactory.getLogger(NoExceptionRestTemplateResponseEntityExtractor.class);
    private final HttpMessageConverterExtractor<T> delegate;

    NoExceptionRestTemplateResponseEntityExtractor(Type responseType, List<HttpMessageConverter<?>> converters) {
        if (responseType != null && Void.class != responseType) {
            this.delegate = new HttpMessageConverterExtractor<>(responseType, converters);
        } else {
            this.delegate = null;
        }
    }

    @Override
    public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
        if (this.delegate != null) {
            T body = null;
            try {
                body = this.delegate.extractData(response);
            } catch (RuntimeException e) {
                String content;
                try {
                    content = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
                    log.error("请求接口时返回[" + content + "],无法解析返回值", e);
                } catch (Exception exception) {
                    content = "";
                    log.error("请求接口时返回未知结果,无法解析返回值", exception);

                }
                return new EraseTypeResponseEntity(content, response.getHeaders(), response.getStatusCode());
            }
            return new ResponseEntity<>(body, response.getHeaders(), response.getStatusCode());
        } else {
            return new ResponseEntity<>(response.getHeaders(), response.getStatusCode());
        }
    }
}
